package itdep.common.context.spring;

import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.*;
import org.drools.compiler.DroolsParserException;
import org.drools.io.impl.InputStreamResource;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.beans.factory.config.AbstractFactoryBean;
import org.springframework.core.io.Resource;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @author Ivan Khalopik
 * @version $Revision: 4 $ $Date: 2010-06-10 13:13:16 +0000 (Thu, 10 Jun 2010) $
 */
public class KnowledgeBaseFactoryBean extends AbstractFactoryBean<KnowledgeBase> {
	private List<Resource> drlResources;
	private Map<String, String> knowledgeBuilderProperties;

	@Required
	public void setDrlResources(final List<Resource> drlResources) {
		this.drlResources = drlResources;
	}

	public void setKnowledgeBuilderProperties(final Map<String, String> knowledgeBuilderProperties) {
		this.knowledgeBuilderProperties = knowledgeBuilderProperties;
	}

	@Override
	public Class<? extends KnowledgeBase> getObjectType() {
		return KnowledgeBase.class;
	}

	@Override
	protected KnowledgeBase createInstance() throws Exception {
		final KnowledgeBuilderConfiguration configuration = KnowledgeBuilderFactory.newKnowledgeBuilderConfiguration();
		for (Map.Entry<String, String> entry : knowledgeBuilderProperties.entrySet()) {
			configuration.setProperty(entry.getKey(), entry.getValue());
		}
		final KnowledgeBuilder builder = KnowledgeBuilderFactory.newKnowledgeBuilder();
		for (Resource resource : drlResources) {
			builder.add(new InputStreamResource(resource.getInputStream()), ResourceType.DRL);
		}
		if (builder.hasErrors()) {
			final StringBuilder sb = new StringBuilder();
			for (KnowledgeBuilderError error : builder.getErrors()) {
				sb.append("Error at lines ").append(Arrays.toString(error.getErrorLines())).append(":").append("\n");
				sb.append(error.getMessage()).append("\n");
			}
			throw new DroolsParserException(sb.toString());
		}
		final KnowledgeBase knowledgeBase = KnowledgeBaseFactory.newKnowledgeBase();
		knowledgeBase.addKnowledgePackages(builder.getKnowledgePackages());
		return knowledgeBase;
	}
}
